const path = require('path')
const fs = require('fs-extra')
const https = require('https')
const http = require('http')
const unzipper = require('unzipper')

const pathMap = require('../pathMap')

// 下载json
async function downloadJSON(data, dest) {
  await fs.ensureDir(path.dirname(dest))
  return new Promise((resolve) => {
    fs.writeFile(dest, JSON.stringify(data), 'utf-8', (err) => {
      resolve(err || `JSON下载成功: ${dest}`)
    })
  })
}

// 下载文件
async function downloadFile({ url, dest }) {
  const destisExists = await fs.pathExists(dest)
  if (destisExists) return console.log(`缓存 ${url}`)
  const dir = path.dirname(dest)
  await fs.ensureDir(dir)
  return new Promise((resolve, reject) => {
    const stream = fs.createWriteStream(dest)
    const ht = url.startsWith('https') ? https : http
    ht.get(url, (res) => {
      // 因为网络下载失败
      if (res.statusCode !== 200) {
        const m = `文件下载失败: ${res.statusCode}, ${url}`
        console.log(m)
        return reject(res)
      }

      stream
        .on('finish', () => {
          console.log(`文件下载成功：${url}`)
          stream.close(resolve)
        })
        .on('error', (err) => {
          if (fs.pathExistsSync(dest)) {
            fs.removeSync(dest)
          }
          console.log(`文件下载失败: ${err.message}`)
          reject(error)
        })

      res.pipe(stream)
    })
  })
}

// 删除离线文件
function removeOfflineFile() {
  const removePaths = [pathMap.api, pathMap.images, pathMap.video, pathMap.xml, pathMap.pano_images]
  removePaths.forEach(async (item) => {
    const isExists = await fs.pathExists(item)
    if (!isExists) return
    fs.emptyDir(item)
  })
}

function unzip({ dist, target }, shouldRemove = true) {
  return new Promise((resolve, reject) => {
    const writer = fs.createReadStream(target).pipe(unzipper.Extract({ path: dist }))
    writer.on('finish', () => {
      // 不停留会少一部分文件
      resolve(dist)
      setTimeout(() => {
        if (shouldRemove) {
          const isExists = fs.pathExists(target)
          if (!isExists) return
          return fs.remove(target)
        }
      }, 1000)
    })
    writer.on('error', reject)
  })
}

module.exports = {
  downloadJSON,
  downloadFile,
  removeOfflineFile,
  unzip,
}
